﻿using System;
using JESAI.HttpRequestMonitor.Core.Abstracts;
using JESAI.HttpRequestMonitor.Core.Builders;
using JESAI.HttpRequestMonitor.Core.Creator;
using JESAI.HttpRequestMonitor.Dashboard.Implements;
using JESAI.HttpRequestMonitor.Dashboard.Models;
using JESAI.HttpRequestMonitor.Dashboard.Services;
using JESAI.HttpRequestMonitor.Dashboard.Services.Language;
using JESAI.HttpRequestMonitor.Dashboard.Services.Quartz;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using Quartz.Spi;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class DependencyInjectionExtensions
    {
        public static IHttpRequestMonitorBuilder AddHttpRequestMonitorDashboard(this IServiceCollection services)
        {
            IConfiguration configuration = services.BuildServiceProvider().GetService<IConfiguration>().GetSection("HttpRequestMonitorDashboard");

            services.AddOptions();
            services.Configure<DashboardOptions>(configuration);

            return services.UseHttpRequestMonitorDashboardService(configuration);
        }



        public static IHttpRequestMonitorBuilder AddHttpRequestMonitorDashboard(this IServiceCollection services, Action<DashboardOptions> options)
        {

            IConfiguration configuration = services.BuildServiceProvider().GetService<IConfiguration>().GetSection("HttpRequestMonitorDashboard");

            services.AddOptions();
            services.Configure<DashboardOptions>(options);

            return services.UseHttpRequestMonitorDashboardService(configuration);
        }


        private static IHttpRequestMonitorBuilder UseHttpRequestMonitorDashboardService(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddSingleton<IModelCreator, DefaultModelCreator>();

            services.AddSingleton<IAlarmService, AlarmService>();

            services.AddSingleton<MonitorService>();

            services.AddSingleton<ScheduleService>();

            services.AddSingleton<ChineseLanguage>();
            services.AddSingleton<EnglishLanguage>();
            services.AddSingleton<LanguageService>();

            services.AddMvcCore(x =>
            {
                x.Filters.Add<GlobalAuthorizeFilter>();
            }).AddViews();

            ServiceContainer.provider = services.BuildServiceProvider();

            return new HttpRequestMonitorBuilder(services, configuration);
        }

        public static IApplicationBuilder UseHttpRequestMonitorDashboard(this IApplicationBuilder app)
        {
            //ServiceContainer.provider = app.ApplicationServices as ServiceProvider; 

            ConfigRoute(app);

            ConfigStaticFiles(app);

            var storage = app.ApplicationServices.GetRequiredService<IRequestMonitorStorage>() ?? throw new ArgumentNullException("未正确配置存储方式");
            storage.InitAsync().Wait();

            app.ApplicationServices.GetService<ScheduleService>().InitAsync().Wait();

            return app;
        }


        /// <summary>
        /// Add access to static resources on debug mode
        /// </summary>
        /// <param name="app"></param>
        private static void ConfigStaticFiles(IApplicationBuilder app)
        {
            if (System.IO.Directory.Exists(System.IO.Path.Combine(AppContext.BaseDirectory, @"wwwroot\HttpRequestMonitorStaticFiles")))
            {
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(System.IO.Path.Combine(AppContext.BaseDirectory, @"wwwroot\HttpRequestMonitorStaticFiles")),
                    RequestPath = new Microsoft.AspNetCore.Http.PathString("/HttpRequestMonitorStaticFiles")

                });
            }
        }


        /// <summary>
        /// Configure user routing  
        /// </summary>
        /// <param name="UseHome"></param>
        /// <param name="app"></param>
        private static void ConfigRoute(IApplicationBuilder app)
        {
            var options = app.ApplicationServices.GetRequiredService<IOptions<DashboardOptions>>().Value;

            app.Use(async (context, next) =>
            {
                if (context.Request.Path.HasValue)
                {
                    if (context.Request.Path.Value.ToLower() == (options.UseHome ? "/" : "dashboard"))
                    {
                        context.Request.Path = "/HttpRequestMonitor";
                    }
                }

                await next();

            });

        }


    }
}